package com.ccy.search;


import com.ccy.search.vo.SearchParam;
import com.ccy.search.vo.SearchResult;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.Arrays;

@SpringBootTest
public class ProductSearch {



    @Autowired
    private RestHighLevelClient client;


    @Test
    public void search() throws IOException {

        //0. 模拟测试数据
        SearchParam searchParam = buildSearchParam();


        //1. 构建searchRequest
        SearchRequest searchRequest = buildSearchRequest(searchParam);

        //2. 执行查询
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        //3. 解析结果

        SearchResult searchResult = analyzerResponse(searchResponse);


    }

    private SearchResult analyzerResponse(SearchResponse searchResponse) {
        SearchResult searchResult = new SearchResult();


        return searchResult;
    }

    private SearchRequest buildSearchRequest(SearchParam searchParam) throws IOException {

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();


        //1. query
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // query -- skutitle
        MatchQueryBuilder skuTitleMatchQuery = QueryBuilders.matchQuery("skuTitle", searchParam.getKeyword());
        boolQueryBuilder.must(skuTitleMatchQuery);

        boolQueryBuilder.filter(QueryBuilders.termQuery("catalogId",searchParam.getCatalog3Id()));
        boolQueryBuilder.filter(QueryBuilders.termsQuery("brandId",searchParam.getBrandId()));
        boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",searchParam.isHasStock()));


        String[] prices = searchParam.getSkuPrice().split("_");
        RangeQueryBuilder skuPriceRangeQuery = QueryBuilders.rangeQuery("skuPrice");
        skuPriceRangeQuery.gte(prices[0]);
        skuPriceRangeQuery.lte(prices[1]);
        boolQueryBuilder.filter(skuPriceRangeQuery);


        BoolQueryBuilder boolQueryBuilder1 = QueryBuilders.boolQuery();
        boolQueryBuilder1.must(QueryBuilders.termQuery("attrs.attrId","10"));
        boolQueryBuilder1.must(QueryBuilders.termsQuery("attrs.attrValue","168","1998"));
        NestedQueryBuilder attrsQueryBuilder = QueryBuilders.nestedQuery("attrs", boolQueryBuilder1, ScoreMode.None);
        boolQueryBuilder.filter(attrsQueryBuilder);



        sourceBuilder.query(boolQueryBuilder);
        //2. sort

        sourceBuilder.sort("skuPrice", SortOrder.DESC);
        //3. from
        sourceBuilder.from(0);
        //4. size
        sourceBuilder.size(20);

        //5. highlight

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("skuTitle");
        highlightBuilder.preTags("<span style='color:skyblue'>");
        highlightBuilder.postTags("</span>");


        sourceBuilder.highlighter(highlightBuilder);

        //6. aggs
        TermsAggregationBuilder brandAgg = AggregationBuilders.terms("brandAgg").field("brandId");
        TermsAggregationBuilder brandNameAgg = AggregationBuilders.terms("brandNameAgg").field("brandName.keyword");
        TermsAggregationBuilder brandImgAgg = AggregationBuilders.terms("brandImgAgg").field("brandImgAgg.keyword");

        TermsAggregationBuilder catalogAgg = AggregationBuilders.terms("catalogAgg").field("catalogId");
        TermsAggregationBuilder catalogNameAgg = AggregationBuilders.terms("catalogNameAgg").field("catalogNameAgg.keyword");

        NestedAggregationBuilder nested = AggregationBuilders.nested("attrsAgg", "attrs");
        TermsAggregationBuilder attrIdAgg = AggregationBuilders.terms("attrIdAgg").field("attrs.attrId");
        TermsAggregationBuilder attrNameAgg = AggregationBuilders.terms("attrNameAgg").field("attrs.attrName");

        brandAgg.subAggregation(brandNameAgg);
        brandAgg.subAggregation(brandImgAgg);

        catalogAgg.subAggregation(catalogNameAgg);

        nested.subAggregation(attrIdAgg);
        attrIdAgg.subAggregation(attrNameAgg);


        sourceBuilder.aggregation(brandAgg);
        sourceBuilder.aggregation(catalogAgg);
        sourceBuilder.aggregation(nested);


        // 查询主体部分
        SearchRequest  searchRequest = new SearchRequest();

        searchRequest.indices("product");
        searchRequest.source(sourceBuilder);

        System.out.println(sourceBuilder.toString());

        return searchRequest;

    }

    private SearchParam buildSearchParam() {

        SearchParam searchParam = new SearchParam();

        searchParam.setKeyword("华为");
        searchParam.setAttrs(Arrays.asList("2_2020:1998","10_168:1998"));
        searchParam.setBrandId(Arrays.asList(Long.valueOf("2")));
        searchParam.setCatalog3Id(Long.valueOf("225"));
        searchParam.setSort("skuPrice_desc");
        searchParam.setHasStock(true);
        searchParam.setSkuPrice("40_20000");
        searchParam.setPageNum(1);


        return searchParam;
    }

}
